#include <linux/list.h>
#include <linux/vmalloc.h>
#include <linux/kernel.h> 

#include "page_table.h"



/*****************************************************************************/

struct page_list pagelist;


/*****************************************************************************/

int pt_create_page_table (void)
{
    INIT_LIST_HEAD(&pagelist.p_head);
    pagelist.next_ent = NULL;
    printk(KERN_INFO "DBG: Page_list created\n");
    return 0;
}


int destroy_page_list(void){
	struct list_head *pos, *q;
	struct page_list *temp;
	
	list_for_each_safe(pos, q, &pagelist.p_head){
		temp = list_entry(pos, struct page_list, p_head);
//		printk(KERN_INFO "DBG: removed from page_list ent ID = %d\n", (temp->next_ent->page_id_o));
		list_del(pos);
		vfree(temp);
	}
	printk(KERN_INFO "DBG: Page_list destroyed\n");
	return 0;
}

int pt_find_entry(int pgid, struct pt_ent_xyz *entry_ret)
{
    struct list_head *pos;
    struct page_list *temp = NULL;
    
	
	list_for_each(pos, &pagelist.p_head){
		temp = list_entry(pos, struct page_list, p_head);
		if((temp->next_ent->page_id_o) == pgid){
			entry_ret = (temp->next_ent);
			return 0;
		}
		

	}
	return -1;	 
}



int pt_insert_entry(struct pt_ent_xyz *entry)
{
 struct page_list *temp;
	
	temp = (struct page_list *)vmalloc(sizeof(struct page_list));

	printk(KERN_INFO"DBG: start insert_page_list->ID = %u\n", (entry->page_id_o));
	if((pt_find_entry(entry->page_id_o, (temp->next_ent))) == 0){
		(temp->next_ent) = entry;
		vfree(temp);
		printk(KERN_INFO "DBG: ID found in page_list, updated\n");
	}else{
//		tmpnl = NULL;
		(temp->next_ent) = entry;
//		printk(KERN_INFO"DBG: tmpnl->nent->ID = %u\n", (tmpnl->nent->neigh_id_o));
		list_add_tail(&(temp->p_head), &(pagelist.p_head));
		printk(KERN_INFO "DBG: Inserting new ent into nlist\n");
		printk(KERN_INFO "DBG: page_list new ent ID = %u\n", (temp->next_ent->page_id_o));

	}
	
	return 0; 
}





int pt_delete_entry(int pgid)
{
	struct list_head *pos, *q;
	struct page_list *temp;
	
	list_for_each_safe(pos, q, &pagelist.p_head){
		temp = list_entry(pos, struct page_list, p_head);
		if((temp->next_ent->page_id_o) == pgid){
			list_del(pos);
			vfree(temp);
			return 0;
			
		}
	}
printk(KERN_INFO "DBG: ID not found in page_list, nothing to remove\n");
return -1; 
}

/********************************************************************************************************/

/*
int main(void)
{
struct key *ktmp, *kktmp;
struct value *vtmp, *foundtmp;
struct page_list *htmp;
struct ent *etmp,etmp2;
int i;
pt_create_page_table();

etmp = (struct ent *)vmalloc(sizeof(struct ent));
    if (NULL == etmp) {
        printk("ERR: ran out of memory allocating a ent\n");
        return 1;
    }
for (i = 0; i < 10; i++)
    {

etmp->page_id_o = 1+i;
etmp->node_id_o = 10+i;
etmp->address_o = 20+i;
printk("DBG: pred insert_entry\n");
pt_insert_entry(etmp);
printk("DBG: za insert_entry\n");
    }

pt_delete_entry(5);

for (i = 0; i < 10; i++)
    {

*etmp = pt_find_entry(1+i);
if (NULL == etmp) {
        printk("ERR: nenasiel sa prvok\n");
    }
else
{
printk("page_id %i \nnode_id %i \naddress %i \n", etmp->page_id_o, etmp->node_id_o, etmp->address_o );
}
}


return 0;
}
*/



